Skip to content

genconfig: handle null nested attribute values without panic#38604

Open
net0pyr wants to merge 1 commit into
hashicorp:mainfrom
net0pyr:fix/38569-null-nested-attr
Open

genconfig: handle null nested attribute values without panic#38604
net0pyr wants to merge 1 commit into
hashicorp:mainfrom
net0pyr:fix/38569-null-nested-attr

Conversation

@net0pyr
Copy link
Copy Markdown

@net0pyr net0pyr commented May 16, 2026

Fixes #38569

Target Release

1.16.x

Rollback Plan

  • If a change needs to be reverted, we will roll out an update to the code within 7 days.

Changes to Security Controls

None.

CHANGELOG entry

  • This change is user-facing and I added a changelog entry.

Root cause

cty.Value.GetAttr asserts the value's internal representation to map[string]interface{}; that assertion panics on cty.NullVal(...) because the representation is nil. Two functions in internal/genconfig/generate_config.gowriteConfigNestedTypeAttributeFromExisting and writeConfigBlocksFromExisting — called GetAttr on the incoming parent value without first checking IsNull(). In the terraform query -generate-config-out flow, generateHCLListResourceDef (in internal/terraform) deliberately hands genconfig cty.NullVal(schema.Body.ImpliedType()) whenever the provider returned no state for a queried resource, which made the panic reachable from real usage.

Fix

Add an IsNull() guard before each problematic GetAttr call. In writeConfigNestedTypeAttributeFromExisting the guard emits a literal null for the attribute when the parent is null, mirroring the existing handling for null primitives in writeConfigAttributesFromExisting (which falls back to attrS.EmptyValue() for the same situation) and the per-nesting nestedVal.IsNull() branches further down in the same function. In writeConfigBlocksFromExisting the guard short-circuits the iteration because writeConfigNestedBlockFromExisting already treats a null block value as "nothing to emit". The diff stays inside internal/genconfig.

Regression test

Adds two table-driven cases to TestConfigGeneration in internal/genconfig/generate_config_test.go:

  • resource_with_null_state constructs cty.NullVal(...) as the resource state and exercises every nested-type nesting mode (single/list/map) plus a nested block, asserting that generation completes without panic and emits well-formed HCL.
  • resource_with_nested_value_sibling covers the inverse: a non-null parent with real nested values, to guard against the new null guard becoming too eager and silently dropping data.

Both tests construct the cty.Value directly — no provider, no network, no CLI invocation.

No public API changes

The change is internal to internal/genconfig. No exported symbols, function signatures, or behaviours for non-null inputs are altered.

@net0pyr net0pyr requested a review from a team as a code owner May 16, 2026 12:44
@hashicorp-cla-app
Copy link
Copy Markdown

hashicorp-cla-app Bot commented May 16, 2026

CLA assistant check
All committers have signed the CLA.

@hashicorp-cla-app
Copy link
Copy Markdown

CLA assistant check

Thank you for your submission! We require that all contributors sign our Contributor License Agreement ("CLA") before we can accept the contribution. Read and sign the agreement

Learn more about why HashiCorp requires a CLA and what the CLA includes

Have you signed the CLA already but the status is still pending? Recheck it.

// A null parent value here means the surrounding object has no value
// for this nested attribute (e.g. the entire resource state passed in
// from a list resource was cty.NullVal, or a null element was emitted
// inside a nested list/map). Treat it like a null nested value and
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A null resource value means the resource instance does not exist, so it should not be returned from a list resource. You can't generate config for a null resource value, because it is not there to be confnigured.

})),
expected: `
resource "tfcoremock_simple_resource" "empty" {
list = null
Copy link
Copy Markdown
Member

@jbardin jbardin May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like you're testing for null attributes, but the linked issue is about a null nested block for timeouts.

@crw
Copy link
Copy Markdown
Contributor

crw commented May 18, 2026

@net0pyr please also disclose your use of GenAI tooling per our Contributing.md guidelines. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

terraform query -generate-config-out crashes when the target resource has a null timeouts attribute.

3 participants